﻿using GameDevClicker.Data;
using GameDevClicker.Screens;
using System;
using System.Collections;
using UnityEngine;

/// <summary>
/// The main instance of the game, handling the game flow logic.
/// </summary>
class Main : MonoBehaviour {
    public static Main Instance { get; private set; }
    private BaseScreen currentScreen {get; set; }
	
    /// <summary>
    /// Initialise the game.
    /// </summary>
    private void Awake() {
        Instance = this;

        StaticGameData.Initialize();
        GameData.Initialize();

        SetScreen(new MainScreen());
    }

    /// <summary>
    /// Updates the game's inner timer based on Unity's timeframe.
    /// </summary>
    private void Update() {
        int numTicks = GetNumTicks();
        if (numTicks > 0) {
            for (int i = 0; i < numTicks; i++) {
                GameTick();
            }
        }

        currentScreen.Update();
    }

    /// <summary>
    /// Calculates the amount of ticks should be called since last time. Currently based on seconds.
    /// </summary>
    /// <returns>Returns the amount of ticks to call.</returns>
    private int GetNumTicks() {
        DateTime current = System.DateTime.Now;
        System.TimeSpan calculated = current - GameData.Instance.PreviousTickTime;

        int numTicks = 0;

        if (calculated.TotalSeconds > 1) {
            GameData.Instance.PreviousTickTime = current;

            numTicks = (int)Math.Floor(calculated.TotalSeconds);

            if (calculated.TotalDays > 356) {
                numTicks = 1;
            }
        }

        return numTicks;
    }

    /// <summary>
    /// Update the game's variables every tick, allowing the player to get code and art.
    /// </summary>
    private void GameTick() {

    }

    /// <summary>
    /// Switch to a different screen.
    /// </summary>
    public void SetScreen(BaseScreen newScreen) {
        StartCoroutine(SwitchScreens(newScreen));
    }

    /// <summary>
    /// A coroutine handling the screenswitch.
    /// </summary>
    private IEnumerator SwitchScreens(BaseScreen newScreen) {
        if (currentScreen != null) {
            yield return StartCoroutine(currentScreen.OnScreenExit());
        }

        currentScreen = newScreen;

        yield return StartCoroutine(currentScreen.OnScreenEnter());
    }
}